-- 2022-8-15

--[[ 17.1.3 搜索器

    在现实中 函数require比此前描述的稍微复杂一点 搜索Lua文件和C标准库的方式只是更加通用的搜索器(searcher)的两个实例
    一个搜索器是一个以模块名为参数 以对应模块的加载器或nil(如果找不到加载器)为返回值的简单函数

    数组package.searchers列出了函数require使用的所有搜索器
    在寻找模块时 函数require传入模块名并调用列表中的每一个搜索器直到它们其中的一个找到了指定模块的加载器
    如果所有搜索器都被调用完后还找不到 那么函数require就抛出一个异常

    用一个列表来驱动对一个模块的搜索给函数require提供了极大的灵活性
    例如 如果想保存被压缩在zip文件中的模块 只需要提供一个合适的搜索器(函数) 然后把它增加到该列表中
    在默认配置中 我们此前学习过的用于搜索Lua文件和C标准库的搜索器排在列表的第二 三位 在它们之前是预加载搜索器

    预加载(preload)搜索器使得我们能够为要加载的模块定义任意的加载函数
    预加载搜索器使用一个名为package.preload的表来映射名称和加载函数
    当搜索指定的模块名时 该搜索器只是简单的在表中搜索指定的名称
    如果它找到了对应的函数 那么就将该函数作为相应模块的加载函数返回 否则 返回nil 
    预加载搜索器为处理非标场景提供了一种通用的方式
    例如 一个静态链接到Lua中的C标准库可以将其luaopen_函数注册到表preload中 这样luaopen_函数之一当用户加载到这个模块时才会被调用
    用这种方式 程序不会为没有用到的模块浪费资源

    默认的package.searchers中的第4个函数只与子模块有关 我们会在17.3节对其进行介绍
]]